package service

import (
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"github.com/gogf/gf/container/gmap"
	"github.com/gogf/gf/encoding/gurl"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
	"github.com/gogf/gf/os/grpool"
	"github.com/gogf/gf/os/gtime"
	"github.com/gogf/gf/text/gregex"
	"github.com/gogf/gf/text/gstr"
	"sync"
	"time"
)

type playList struct {
	path       string
	host       string
	scheme     string
	delimiter  string
	httpClient *ghttp.Client
	httpPool   *grpool.Pool
	episodes   *gmap.StrStrMap
}

var PlayList = playList{
	httpClient: ghttp.NewClient().SetHeaderMap(g.MapStrStr{
		"accept":     "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
		"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36",
	}).SetTimeout(30 * time.Second),
	httpPool:  grpool.New(6),
	episodes:  gmap.NewStrStrMap(true),
	delimiter: "://",
}

func (pl *playList) SetUrlPath(path string) *playList {
	pl.path = path
	return pl
}

func (pl *playList) Run() {
	url, _ := gurl.ParseURL(pl.path, -1)
	pl.host = url["host"]
	pl.scheme = url["scheme"]
	pl.Episodes()
	pl.ParseM3u8SwapUrl()
	fmt.Println(gtime.Datetime(), "parse m3u8 url start")
	g.Dump(pl.episodes.Map())
	pl.ParseM3u8Url()
	fmt.Println(gtime.Datetime(), "parse m3u8 url end")
	M3u8.Run(pl.episodes)
}

//ParseM3u8Url 解析出每一集的m3u8地址
func (pl *playList) ParseM3u8Url() {
	group := sync.WaitGroup{}
	for title, href := range pl.episodes.Map() {
		group.Add(1)
		//处理并发覆写
		t := title
		h := href
		_ = pl.httpPool.Add(func() {
			fmt.Println(t, h)
			get, err := pl.httpClient.Get(h)
			if err != nil {
				fmt.Println(err)
				return
			}
			defer get.Close()
			body := get.ReadAllString()
			fmt.Println(t, h, body)
			addr, _ := gregex.MatchString(`"url":"(.*)","name`, body)
			if len(addr) == 0 {
				fmt.Println(body, addr)
			} else {
				pl.episodes.Set(t, gstr.Replace(gstr.Replace(addr[1], "\\", ""), "/index.m3u8", "/1000kb/hls/index.m3u8"))
			}
			//if len(addr) > 1 {
			//	pl.episodes.Set(t, "https://jx.huishij.com/yun/?url="+gstr.Replace(addr[1], "\\", ""))
			//}
			group.Done()
		})
	}
	group.Wait()
	return
}

//ParseM3u8SwapUrl 解析出每一集的m3u8兑换地址
func (pl *playList) ParseM3u8SwapUrl() {
	group := sync.WaitGroup{}
	for title, href := range pl.episodes.Map() {
		group.Add(1)
		//处理并发覆写
		t := title
		h := href
		_ = pl.httpPool.Add(func() {
			get, err := pl.httpClient.Get(pl.scheme + pl.delimiter + pl.host + h)
			if err != nil {
				fmt.Println(err)
				return
			}
			defer get.Close()
			element, err := goquery.NewDocumentFromReader(get.Body)
			if err != nil {
				fmt.Println(err)
				return
			}
			html, err := element.Html()
			if err != nil || html == "" {
				fmt.Println(err)
				return
			}
			element.Find("script").EachWithBreak(func(i int, selection *goquery.Selection) bool {
				attr, _ := selection.Attr("src")
				if gstr.ContainsI(attr, "97bike") {
					url, _ := gurl.Decode(attr)
					//fmt.Println(t,pl.scheme+":"+url)
					pl.episodes.Set(t, pl.scheme+":"+url)
				}
				return true
			})
			group.Done()
		})
	}
	group.Wait()
	return
}

// Episodes 解析集数与对应地址
func (pl *playList) Episodes() {
	get, err := pl.httpClient.Get(pl.path)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer get.Close()
	element, err := goquery.NewDocumentFromReader(get.Body)
	if err != nil {
		fmt.Println(err)
		return
	}
	html, err := element.Html()
	if err != nil || html == "" {
		fmt.Println(err)
		return
	}
	element.Find("#con_playlist_1 li").Each(func(i int, selection *goquery.Selection) {
		title, _ := selection.Find("a").Attr("title")
		href, _ := selection.Find("a").Attr("href")
		//fmt.Println(title, href)
		pl.episodes.Set(title, href)
	})
	return
}
